home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / BORLAND TURBO / OWLSRC.PAK / OLEFRAME.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-06  |  18.5 KB  |  747 lines

  1. //----------------------------------------------------------------------------
  2. // ObjectWindows
  3. // Copyright (c) 1994, 1997 by Borland International, All Rights Reserved
  4. //
  5. //$Revision:   10.8  $
  6. //
  7. // Implementation of class TOleFrame.
  8. //----------------------------------------------------------------------------
  9. #define INC_OLE2
  10. #include <owl/pch.h>
  11. #if !defined(OWL_DECMDIFR_H)
  12. # include <owl/decmdifr.h>
  13. #endif
  14. #if !defined(OWL_STATUSBA_H)
  15. # include <owl/statusba.h>
  16. #endif
  17. #if !defined(OWL_OCFEVENT_H)
  18. # include <owl/ocfevent.h>
  19. #endif
  20. #if !defined(OWL_OLEFRAME_H)
  21. # include <owl/oleframe.h>
  22. #endif
  23. #if !defined(OWL_OLEWINDO_H)
  24. # include <owl/olewindo.h>
  25. #endif
  26. #if !defined(OWL_COMMCTRL_H)
  27. # include <owl/commctrl.h>
  28. #endif
  29.  
  30. OWL_DIAGINFO;
  31. DIAG_DEFINE_GROUP_INIT(OWL_INI, OwlOleMenu, 1, 0);
  32. DIAG_DECLARE_GROUP(OwlCmd);
  33.  
  34. //#define DEBUG_PADS
  35. // define to make pads paint red for debugging time in MS for idle action polling
  36. const int DllIdleTime = 200;
  37.  
  38. // Four edge locations for inplace-server space negotiation
  39. //
  40. const TDecoratedFrame::TLocation SpaceLoc[] = {
  41.   TDecoratedFrame::Left,
  42.   TDecoratedFrame::Top,
  43.   TDecoratedFrame::Right,
  44.   TDecoratedFrame::Bottom
  45. };
  46.  
  47. //----------------------------------------------------------------------------
  48. // An empty no-erase window that inserts itself into its decorated frame
  49. // parent
  50. //
  51.  
  52. class TPadWindow : public TWindow {
  53.   public:
  54.     TPadWindow(TWindow* parent, int edge, TModule* module = 0)
  55.       : TWindow(parent, 0, module)
  56.     {
  57.       Attr.Id = IDW_PADDECORATION+edge;
  58.       Attr.Style = WS_CHILD | WS_VISIBLE;
  59.       Attr.W = Attr.H = 1;             // takeup no space until needed
  60.                                        // need 1 since layout overlapps borders
  61. #if defined(DEBUG_PADS)
  62.       SetBkgndColor(TColor(255,0,0));  // to help Debug toolbar negotiations
  63.       strstream s;
  64.       s << "Pad" << ('0' + edge);
  65.       Title = strnewdup(s.str());
  66. #else
  67.       SetBkgndColor(NoErase);          // Don't erase--to avoid flicker
  68. #endif
  69.     }
  70. };
  71.  
  72. //
  73. // class TRemViewBucket
  74. // ~~~~~ ~~~~~~~~~~~~~~
  75. // A small window class to act as a holder for the unattached remote server
  76. // view windows
  77. //
  78. class _CALLCNVN TRemViewBucket : public TFrameWindow {
  79.   public:
  80.     TRemViewBucket(TWindow* parent);
  81.     
  82.     // Overriden virtuals of base class
  83.     //
  84.     bool      SetDocTitle(const char far*, int);
  85.  
  86.     // Override handlers to act as pass-thru on behalf of remove server view
  87.     //
  88.     TResult   EvCommand(uint id, THandle hWndCtl, uint notifyCode);
  89.     TResult   EvNotify(uint id, TNotify far& notifyInfo);
  90.     void      EvCommandEnable(TCommandEnabler& ce);
  91.     TWindow*  FindRemoteWindow();
  92. };
  93.  
  94. //
  95. //
  96. //
  97. TRemViewBucket::TRemViewBucket(TWindow* parent) 
  98.                :TFrameWindow(parent, "RemViewBucket")
  99. {
  100.   Attr.Style = WS_CHILD | WS_DISABLED;
  101.   Attr.Id = IDW_REMVIEWBUCKET;
  102. }
  103.  
  104. //
  105. //
  106. //
  107. bool
  108. TRemViewBucket::SetDocTitle(const char far*, int)
  109. {
  110.   return true;
  111. }
  112.  
  113. //
  114. //
  115. //
  116. TWindow*  
  117. TRemViewBucket::FindRemoteWindow()
  118. {
  119.   // Check if we can find the object representing the remote window object by
  120.   // traversing the focus window tree
  121.   //
  122.   TWindow* remote = 0;
  123.   HWND focusHwnd  = GetFocus();
  124.   HWND hwnd       = focusHwnd;
  125.   while (hwnd) {
  126.     remote = GetWindowPtr(hwnd);
  127.     if (remote) {
  128.       // The remote window has the remViewBucket as its parent
  129.       //
  130.       if (remote->GetParentO() == this)
  131.         break;
  132.       else
  133.         remote = 0;
  134.     }
  135.     hwnd = ::GetParent(hwnd);
  136.   }
  137.   return remote;
  138. }
  139.  
  140. //
  141. //
  142. //
  143. TResult   
  144. TRemViewBucket::EvCommand(uint id, THandle hWndCtl, uint notifyCode)
  145. {
  146. #if !defined(_OWLDLL)
  147.   TRACEX(OwlCmd, 1, "TRemViewBucket::EvCommand - id(" << id << "), ctl(" <<\
  148.                      hex << uint(hWndCtl) << "), code(" << notifyCode  << ")");
  149. #endif
  150.  
  151.   // Find remote view
  152.   //
  153.   TWindow* handler = FindRemoteWindow();
  154.   
  155.   // Default to parent if none was found
  156.   //
  157.   if (!handler)
  158.     handler = GetParentO();
  159.  
  160. #if !defined(_OWLDLL)
  161.   TRACEX(OwlCmd, 1, "TRemViewBucket::EvCommand - forwarding to " << *handler);
  162. #endif
  163.  
  164.   // Forward event
  165.   //
  166.   CHECK(handler);
  167.   return handler->EvCommand(id, hWndCtl, notifyCode);
  168. }
  169.  
  170. //
  171. //
  172. //
  173. TResult   
  174. TRemViewBucket::EvNotify(uint id, TNotify far& notifyInfo)
  175. {
  176. #if !defined(_OWLDLL)
  177.   TRACEX(OwlCmd, 1, "TRemViewBucket::EvNotify - id(" << id << "), ctl("\
  178.                     << hex << uint(notifyInfo.hwndFrom) << "), code(" \
  179.                     << notifyInfo.code  << ")");
  180. #endif
  181.  
  182.   // Find remote view
  183.   //
  184.   TWindow* handler = FindRemoteWindow();
  185.   
  186.   // Default to parent if none was found
  187.   //
  188.   if (!handler)
  189.     handler = GetParentO();
  190.  
  191. #if !defined(_OWLDLL)
  192.   TRACEX(OwlCmd, 1, "TRemViewBucket::EvNotify - forwarding to " << *handler);
  193. #endif
  194.  
  195.   // Forward event
  196.   //
  197.   CHECK(handler);
  198.   return handler->EvNotify(id, notifyInfo);
  199. }
  200.  
  201. //
  202. //
  203. //
  204. void      
  205. TRemViewBucket::EvCommandEnable(TCommandEnabler& ce)
  206. {
  207.   // Find remote view
  208.   //
  209.   TWindow* handler = FindRemoteWindow();
  210.   
  211.   // Default to parent if none was found
  212.   //
  213.   if (!handler)
  214.     handler = GetParentO();
  215.  
  216. #if !defined(_OWLDLL)
  217.   TRACEX(OwlCmd, 1, "TRemViewBucket::EvCommandEnable - forwarding to " << *handler);
  218. #endif
  219.  
  220.   // Forward event
  221.   //
  222.   CHECK(handler);
  223.   handler->EvCommandEnable(ce);
  224. }
  225.  
  226. DEFINE_RESPONSE_TABLE1(TOleFrame, TDecoratedFrame)
  227.   EV_WM_SIZE,
  228.   EV_WM_TIMER,
  229.   EV_WM_ACTIVATEAPP,
  230.  
  231.   EV_MESSAGE(WM_OCEVENT, EvOcEvent),
  232.   EV_OC_APPINSMENUS,
  233.   EV_OC_APPMENUS,
  234.   EV_OC_APPPROCESSMSG,
  235.   EV_OC_APPFRAMERECT,
  236.   EV_OC_APPBORDERSPACEREQ,
  237.   EV_OC_APPBORDERSPACESET,
  238.   EV_OC_APPSTATUSTEXT,
  239.   EV_OC_APPRESTOREUI,
  240.   EV_OC_APPSHUTDOWN,
  241. END_RESPONSE_TABLE;
  242.  
  243. //
  244. //
  245. //
  246. TOleFrame::TOleFrame(const char far* title,
  247.                      TWindow*        clientWnd,
  248.                      bool            trackMenuSelection,
  249.                      TModule*        module)
  250. :
  251.   TDecoratedFrame(0, title, clientWnd, trackMenuSelection, module),
  252.   TFrameWindow(0, title, clientWnd, false, module),
  253.   TWindow(0, title, module),
  254.   HOldMenu(0),
  255.   OcApp(0),
  256.   StashCount(0),
  257.   OcShutDown(DontCare)
  258. {
  259.   new TRemViewBucket(this);  // Construct bucket to hold hidden server windows
  260.  
  261.   // Retrieve the OcApp ptr from our owning application if it is a TOcModule
  262.   //
  263.   TOcModule* ocm = TYPESAFE_DOWNCAST(GetApplication(), TOcModule);
  264.   if (ocm)
  265.     SetOcApp(ocm->OcApp);
  266. }
  267.  
  268. //
  269. // Let the OC app go. It will delete itself when it can
  270. //
  271. TOleFrame::~TOleFrame()
  272. {
  273. }
  274.  
  275. //
  276. // Initial set of OcApp being passed to us to use.
  277. //
  278. void
  279. TOleFrame::SetOcApp(TOcApp* ocApp)
  280. {
  281.   PRECONDITION(ocApp);
  282.   OcApp = ocApp;
  283.  
  284.   // Initialize OLE 2 clipboard format names
  285.   //
  286.   char f[] = "%s";
  287.   AddUserFormatName(f, f, ocrEmbedSource);
  288.   AddUserFormatName(f, f, ocrEmbeddedObject);
  289.   AddUserFormatName(f, f, ocrLinkSource);
  290. }
  291.  
  292. //
  293. // Let the OcApp know our THandle so that it can talk to us
  294. //
  295. void
  296. TOleFrame::SetupWindow()
  297. {
  298.   PRECONDITION(OcApp);
  299.   TDecoratedFrame::SetupWindow();
  300.   OcApp->SetupWindow(*this);
  301.  
  302.   // Insert the four pad windows for in-place server toolbars. Inserting last
  303.   // will place them as the inner-most decorations, which is needed with the
  304.   // status bar
  305.   //
  306.   for (int edge = 0; edge < 4; edge++)
  307.     Insert(*new TPadWindow(this, edge), ::SpaceLoc[edge]);
  308.  
  309.   // Create a timer to allow us to poll for idle time when we are a dll server
  310.   //
  311.   if (!OcApp->IsOptionSet(amExeMode))
  312.     SetTimer(IDT_DLLIDLE, DllIdleTime);
  313. }
  314.  
  315. //
  316. //
  317. //
  318. void
  319. TOleFrame::CleanupWindow()
  320. {
  321.   if (!OcApp->IsOptionSet(amExeMode))
  322.     KillTimer(IDT_DLLIDLE);
  323. }
  324.  
  325. //
  326. // Add user defined format and result names to the list
  327. //
  328. void
  329. TOleFrame::AddUserFormatName(const char far* name, const char far* resultName,
  330.                              const char far* id)
  331. {
  332.   PRECONDITION(OcApp);
  333.   OcApp->AddUserFormatName(name, resultName, id);
  334. }
  335.  
  336. //
  337. //
  338. //
  339. void
  340. TOleFrame::OleViewClosing(bool close)
  341. {
  342.   if (close && OcShutDown == DontCare) {
  343.     OcShutDown = ViewInitiated;
  344.   }
  345.   else if (!close && OcShutDown == ViewInitiated) {
  346.     OcShutDown = DontCare;
  347.   }
  348. }
  349.  
  350. // Disconnect document servers with their clients.
  351. // Document servers can be documents with objects copied on the clipboard or
  352. // documents brought up though linking.
  353. //
  354. void
  355. sDisconnectDocServer(TWindow* win, void* /*retVal*/)
  356. {
  357.   if (win) {
  358.     win->ForEach(sDisconnectDocServer);
  359.  
  360.     TOleWindow* oleWin = TYPESAFE_DOWNCAST(win, TOleWindow);
  361.     if (oleWin)
  362.       oleWin->OleShutDown();
  363.   }
  364. }
  365.  
  366. //
  367. // Make sure that any embeded servers also get a chance to OK the close
  368. // sequence. If the user closes the app, but there are still embeddings, hide
  369. // the frame instead of destroying it
  370. //
  371. void
  372. TOleFrame::Destroy(int retVal)
  373. {
  374.   if (!GetHandle() || OcShutDown == UserInitiated)
  375.     return;
  376.  
  377.   // Disconnect document servers with their clients if user shuts down the app
  378.   //
  379.   if (OcShutDown == DontCare) {
  380.     OcShutDown = UserInitiated;
  381.     ForEach(sDisconnectDocServer, 0);
  382.   }
  383.  
  384.   if (!OcApp->CanClose()) {
  385.     OcApp->SetOption(amEmbedding, true);
  386.     OcShutDown = DontCare; // reset the shutdown flag
  387.     ShowWindow(SW_HIDE);
  388.   }
  389.   else {
  390.     bool dllServer = !OcApp->IsOptionSet(amExeMode);
  391.  
  392.     TDecoratedFrame::Destroy(retVal);
  393.  
  394.     // If user shuts down the DLL server (as in the case of open-editing,
  395.     // we need to set the mainwindow flag to 0 so that only the application
  396.     // will be destroyed.  All windows are destroyed in previous calls.
  397.     //
  398.     if (dllServer && OcShutDown != ServerInitiated) {
  399. //      GetApplication()->SetMainWindow(0);
  400.       GetApplication()->MainWindow = 0;
  401.       delete GetApplication();
  402.     }
  403.   }
  404. }
  405.  
  406. //
  407. // Forward size message to OcApp to allow it to notify any embedded servers
  408. // about size changes
  409. //
  410. void
  411. TOleFrame::EvSize(uint sizeType, TSize& size)
  412. {
  413.   TDecoratedFrame::EvSize(sizeType, size);
  414.   if (OcApp)
  415.     OcApp->EvResize();
  416. }
  417.  
  418. //
  419. // Forward Activate messages to OcApp to allow it to notify any embedded servers
  420. // about being activated
  421. //
  422. void
  423. TOleFrame::EvActivateApp(bool active, HTASK hTask)
  424. {
  425.   OcApp->EvActivate(active);
  426.   TDecoratedFrame::EvActivateApp(active, hTask);
  427. }
  428.  
  429. //
  430. //
  431. //
  432. void
  433. TOleFrame::EvTimer(uint timerId)
  434. {
  435.   if (timerId == IDT_DLLIDLE)
  436.     GetApplication()->PostDispatchAction();
  437.   TWindow::EvTimer(timerId);
  438. }
  439.  
  440. //
  441. // Handle & sub-dispatch the OC event message.
  442. //
  443. TResult
  444. TOleFrame::EvOcEvent(TParam1 param1, TParam2 param2)
  445. {
  446.   TEventHandler::TEventInfo eventInfo(WM_OCEVENT, param1);
  447.  
  448.   // Give the client window the first chance at it
  449.   //
  450.   TWindow* receiver = GetClientWindow();
  451.   if (receiver->Find(eventInfo))
  452.     return receiver->Dispatch(eventInfo, param1, param2);
  453.  
  454.   // Then try this frame
  455.   //
  456.   if (Find(eventInfo))
  457.     return Dispatch(eventInfo, param1, param2);
  458.  
  459.   // Last, try the application in case it wants to override events
  460.   //
  461.   if (GetApplication()->Find(eventInfo))
  462.     return GetApplication()->Dispatch(eventInfo, param1, param2);
  463.   return 0;
  464. }
  465.  
  466. //
  467. // Insert our menus into a provided menu bar, possibly merging them with a
  468. // servers.
  469. //
  470. bool
  471. TOleFrame::EvOcAppInsMenus(TOcMenuDescr far& sharedMenu)
  472. {
  473.   if (HOldMenu) {
  474.     TRACEX(OwlOleMenu, 0, "EvOcAppInsMenus called while HOldMenu is " << hex <<
  475.           (uint)HOldMenu);
  476.     return true;
  477.   }
  478.  
  479.   // Recreate a temporary composite menu for frame
  480.   //
  481.   TMenuDescr compMenuDesc; // empty menudescr
  482.   if (GetMenuDescr()) {
  483.     compMenuDesc.Merge(*GetMenuDescr());
  484.  
  485.     // Mask off the server menus
  486.     //
  487.     compMenuDesc.Merge(TMenuDescr(0,  0, -1, 0, -1, 0, -1));
  488.   }
  489.   else
  490.     return false; // stop menu negotiation if we don't have menu
  491.  
  492.   // Merge into the OLE shared menubar
  493.   //
  494.   TMenuDescr shMenuDescr(sharedMenu.HMenu,
  495.                          sharedMenu.Width[0],
  496.                          sharedMenu.Width[1],
  497.                          sharedMenu.Width[2],
  498.                          sharedMenu.Width[3],
  499.                          sharedMenu.Width[4],
  500.                          sharedMenu.Width[5]);
  501.   shMenuDescr.Merge(compMenuDesc);
  502.  
  503.   // Copy the shared menu widths back to the OC struct
  504.   //
  505.   for (int i = 0; i < 6; i++)
  506.     sharedMenu.Width[i] = shMenuDescr.GetGroupCount(i);
  507.  
  508.   // Save the container popups so they can be destroyed later
  509.   //
  510.   StashContainerPopups(shMenuDescr);
  511.  
  512.   TRACEX(OwlOleMenu, 0, "Merged menu " << hex << (uint)sharedMenu.HMenu);
  513.   return true;
  514. }
  515.  
  516. //
  517. // Now, actually set the merged menubar into our frame
  518. //
  519. bool
  520. TOleFrame::EvOcAppMenus(TOcMenuDescr far& appMenus)
  521. {
  522.   if (!appMenus.HMenu) {
  523.     if (HOldMenu) {
  524.       TRACEX(OwlOleMenu, 0, "EvOcAppMenus(0) resetting Old " << hex <<
  525.              (uint)HOldMenu);
  526.       TMenu oleMenu(*this);
  527.       SetMenu(HOldMenu);     // assumes we are just restoring the old owl menu
  528.       HOldMenu = 0;
  529.     }
  530.     DestroyStashedPopups();  // destroy the popup copies we made
  531.     return true;
  532.   }
  533.  
  534.   // Don't set the menu again if we are holding a merged one already
  535.   //
  536.   if (HOldMenu) {
  537.     TRACEX(OwlOleMenu, 0, "EvOcAppMenus called while HOldMenu is " << hex <<
  538.           (uint)HOldMenu);
  539.     return true;
  540.   }
  541.  
  542.   HOldMenu = GetMenu();
  543.   TRACEX(OwlOleMenu, 0, "Saved Old " << hex << (uint)HOldMenu);
  544.  
  545.   SetMenu(appMenus.HMenu);
  546.   TRACEX(OwlOleMenu, 0, "Set merged " << hex << (uint)appMenus.HMenu);
  547.  
  548.   return true;
  549. }
  550.  
  551. //
  552. // Process accelerators and other queued messages from the server's queue in
  553. // our app
  554. //
  555. bool
  556. TOleFrame::EvOcAppProcessMsg(MSG far* msg)
  557. {
  558. #if defined(BI_DATA_NEAR)
  559.   MSG nearMsg = *msg;
  560.   bool ret = GetApplication()->ProcessAppMsg(nearMsg);
  561.   *msg = nearMsg;
  562.   return ret;
  563. #else
  564.   return GetApplication()->ProcessAppMsg(*msg);
  565. #endif
  566. }
  567.  
  568. //
  569. // Let the server know our frame's client rect, minus the status bar height,
  570. // if there is one
  571. //
  572. bool
  573. TOleFrame::EvOcAppFrameRect(TRect far* rect)
  574. {
  575.   PRECONDITION(rect);
  576.   *rect = GetClientRect();
  577.   TWindow*  sb = ChildWithId(IDW_STATUSBAR);
  578.   if (sb) {
  579.     TRect sbr = sb->GetClientRect();
  580.     rect->bottom -= sbr.bottom+1;
  581.   }
  582.   return true;
  583. }
  584.  
  585. //
  586. // Let the server know that we can handle border adornments on all four edges
  587. //
  588. bool
  589. TOleFrame::EvOcAppBorderSpaceReq(TRect far* /*space*/)
  590. {
  591.   return true;
  592. }
  593.  
  594. //
  595. // Actually create space on the requested edges for the server's adornments
  596. //
  597. bool
  598. TOleFrame::EvOcAppBorderSpaceSet(TRect far* space)
  599. {
  600.   // Resize pad decorations based on edges requested
  601.   //
  602.   int* edges = (int*)space;   // treat space as array of 4 int edges
  603.   bool needLayout = false;
  604.   for (int i = 0; i < 4; i++) {
  605.     TWindow*  pad = ChildWithId(IDW_PADDECORATION+i);
  606.     if (pad) {
  607.       int edge = edges && edges[i] ? edges[i]+1 : 1;
  608.       if (i%1 == 0 && pad->Attr.W != edge ||   // left & right edge
  609.           i%1 == 1 && pad->Attr.H != edge) {   // top & bottom edge
  610.         TLayoutMetrics m;
  611.         GetChildLayoutMetrics(*pad, m);
  612.         pad->Attr.H = pad->Attr.W = edge;  // set both axis, one will be stretched
  613.         SetChildLayoutMetrics(*pad, m);
  614.         needLayout = true;
  615.       }
  616.     }
  617.   }
  618.  
  619.   // Turn on/off control bar as needed
  620.   //
  621.   TWindow*  tb = ChildWithId(IDW_TOOLBAR);
  622.   if (tb)
  623.     if (space && tb->IsWindowVisible() || !space && !tb->IsWindowVisible()) {
  624.       SendMessage(WM_COMMAND, IDW_TOOLBAR);  // toggle tool bar on/off
  625.       needLayout = false;  // layout already done now by decorated frame.
  626.     }
  627.  
  628.   // Now do layout once at the end to reduce repaint
  629.   //
  630.   if (needLayout)
  631.     Layout();
  632.  
  633.   return true;
  634. }
  635.  
  636. //
  637. // Display the servers status messages on our status bar
  638. //
  639. void
  640. TOleFrame::EvOcAppStatusText(const char far* text)
  641. {
  642.   TMessageBar* mb = TYPESAFE_DOWNCAST(ChildWithId(IDW_STATUSBAR), TMessageBar);
  643.   if (mb) {
  644.     //mb->SetHintText(text);   // is the text a hint, or general status??
  645. #if defined(BI_DATA_NEAR)
  646.     mb->SetText(string(text).c_str());
  647. #else
  648.     mb->SetText(text);
  649. #endif
  650.   }
  651. }
  652.  
  653. //
  654. // Save off the popup menu handles that are copies so that we can destroy
  655. // them later. Keep track of active object menus, to allow cleanup when
  656. // the last one goes away.
  657. //
  658. void TOleFrame::StashContainerPopups(const TMenuDescr& shMenuDescr)
  659. {
  660.   StashCount++;
  661.  
  662.   int m = 0;
  663.   for (int i = 0; i < 6; i++) {
  664.     if (i%2 == 0)
  665.       for (int j = 0; j < shMenuDescr.GetGroupCount(i); j++) {
  666.         uint  state = shMenuDescr.GetMenuState(m+j, MF_BYPOSITION);
  667.         if (state == uint(-1))
  668.           continue;
  669.         TRACEX(OwlOleMenu, 1, "Stashing " << hex << (uint)shMenuDescr.GetSubMenu(m+j));
  670.         StashedContainerPopups.AppendMenu(state, TMenu(shMenuDescr.GetSubMenu(m+j)), "");
  671.       }
  672.     m += shMenuDescr.GetGroupCount(i);
  673.   }
  674. }
  675.  
  676. //
  677. // Throw away our popup copies that are no longer needed, when the last active
  678. // object is deactivated.
  679. //
  680. void TOleFrame::DestroyStashedPopups()
  681. {
  682.   if (--StashCount)
  683.     return;
  684.  
  685.   while (StashedContainerPopups.GetMenuItemCount()) {
  686.     TRACEX(OwlOleMenu, 1, "Destroying " << hex << (uint)StashedContainerPopups.GetSubMenu(0));
  687.     StashedContainerPopups.DeleteMenu(0, MF_BYPOSITION);
  688.   }
  689. }
  690.  
  691. //
  692. // Restore the UI back to pre-inplace server state. Remove the border space pads
  693. // and restore the menu.
  694. //
  695. void
  696. TOleFrame::EvOcAppRestoreUI()
  697. {
  698.   // Only restore the old menu if we are holding a merged one
  699.   //
  700.   if (HOldMenu) {
  701.     TRACEX(OwlOleMenu, 0, "EvOcAppRestoreUI resetting Old " << hex <<
  702.            (uint)HOldMenu);
  703.     TMenu oleMenu(*this);
  704.     SetMenu(HOldMenu);    // assumes we are just restoring the old owl menu
  705.     HOldMenu = 0;
  706.   }
  707.  
  708.   // Remove pad decorations & restore our toobar if we have one
  709.   //
  710.   EvOcAppBorderSpaceSet(0);
  711. }
  712.  
  713. //
  714. // Called by TOcRemView::Close when last embedding is closed
  715. // If that's the only reason the app is up we need to shut ourselves down
  716. //
  717. bool
  718. TOleFrame::EvOcAppShutdown()
  719. {
  720.   // If TOleFrame was created purely for embedded server, then
  721.   // we want to shut down the app when nobody is using the server.
  722.   // The amEmbedding flag will be set to false if user created normal
  723.   // document in this frame.
  724.   //
  725.   if (OcShutDown == DontCare && OcApp->IsOptionSet(amEmbedding)) {
  726.     // The shut down is initiated by OCF
  727.     //
  728.     OcShutDown = ServerInitiated;
  729.  
  730.     // Post frame close to kill the app later
  731.     //
  732.     PostMessage(WM_CLOSE);
  733.  
  734.     return true;
  735.   }
  736.   else {
  737.  
  738.     // If the last view closing caused the ocapp to shutdown, then close this
  739.     // frame.
  740.     //
  741.     if (OcApp->IsOptionSet(amEmbedding) && OcShutDown == ViewInitiated)
  742.       PostMessage(WM_CLOSE);
  743.  
  744.     return false; // Shut down initiated by user
  745.   }
  746. }
  747.